package ua.edu.nuos.tees.jdmmon.gui.components;

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionListener;
import java.awt.geom.Line2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;

/**
 * Analog indicator for voltage, current and cos phi indicating
 *
 * @author Olha Mudrievska
 *         09.05.13
 */
public class AnalogArrowIndicator extends JPanel {

    private int xCenter;
    private int yCenter;
    private int arrowLength;
    private double startValue;
    private double endValue;
    private double stepAngle;
    private double startAngle;
    private double currentAngle;
    private BufferedImage backgroundImage = null;
    private int xShift;
    private int yShift;
    private JLabel digitalIndicator = new JLabel();

    public AnalogArrowIndicator(URL imageUrl, int xCenter, int yCenter, int arrowLength, double startValue,
                                double endValue, double startAngle, double endAngle) {
        setLayout(new GridBagLayout());
        setImage(imageUrl);
        setCenterCoordinates(xCenter, yCenter);
        setArrowLength(arrowLength);
        setValueLimits(startValue, endValue);
        setStartAngle(startAngle);
        currentAngle = startAngle;
        stepAngle = (endAngle - startAngle) / (endValue - startValue);
        addDigitalIndicator("0.0");
    }

    private void addDigitalIndicator(String initialText){
        GridBagConstraints gbc = new GridBagConstraints();
        digitalIndicator.setOpaque(true);
        digitalIndicator.setForeground(Color.WHITE);
        digitalIndicator.setBackground(new Color(70, 70, 70));
        digitalIndicator.setHorizontalAlignment(SwingConstants.RIGHT);
        digitalIndicator.setFont(new Font("Arial", Font.BOLD, 16));
        digitalIndicator.setText(initialText);
        gbc.anchor = GridBagConstraints.PAGE_START;
        gbc.weighty = 1;
        gbc.insets = new Insets(197, 0, 0, 0);
        gbc.gridx = 0;
        gbc.gridy = 0;
        add(digitalIndicator, gbc);
    }

    /**
     * Set center x, y coordinates of the arrow in millimeters
     * @param xCenter
     * @param yCenter
     */
    public void setCenterCoordinates(int xCenter, int yCenter) {
        this.xCenter = xCenter;
        this.yCenter = yCenter;
    }

    /**
     * Set arrow length in millimeters
     * @param arrowLength the initial arrow length
     */
    public void setArrowLength(int arrowLength) {
        this.arrowLength = arrowLength;
    }

    /**
     * Set value limits
     * @param startValue the initial start value
     * @param endValue the initial end value
     */
    public void setValueLimits(double startValue, double endValue) {
        this.startValue = startValue;
        this.endValue = endValue;
    }

    /**
     * Set start arrow angle in radians
     * @param startAngle start angle
     */
    public void setStartAngle(double startAngle) {
        this.startAngle = startAngle;
    }

    /**
     * Set current value
     * @param value value
     */
    public void setValue(double value) {
        if (value <= endValue)
            value = value >= startValue ? value : startValue;
        else
            value = endValue;
        currentAngle = startAngle + value * stepAngle;
        digitalIndicator.setText(String.valueOf(String.format("%8.2f", value).replace(',', '.')));
        repaint();
    }

    /**
     * Set background image
     * @param imageUrl image URL address
     */
    public void setImage(URL imageUrl) {
        try {
            backgroundImage = ImageIO.read(imageUrl);
        } catch (IOException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        xShift = (this.getSize().width - backgroundImage.getWidth()) / 2;
        yShift = 5;
        Graphics2D g2d = (Graphics2D) g;
        g2d.drawImage(backgroundImage, xShift, yShift, null);
        g2d.setStroke(new BasicStroke(2));
        g2d.setColor(new Color(128, 0, 0));
        g2d.draw(new Line2D.Float(xCenter + xShift, yCenter + yShift, Math.round(Math.cos(currentAngle) * arrowLength) +
                xCenter + xShift, Math.round(Math.sin(currentAngle) * arrowLength) + yCenter + yShift));
    }
}
